#include "Texture2D.h"

#include "stb_image.h"
#include <glad/glad.h>

Texture2D::Texture2D(const std::string &path) : m_filepath(path), m_localBuffer(nullptr), m_width(0), m_height(0), m_channels(0)
{
    // 垂直翻转图像，使输出阵列中的第一个像素位于左下角
    stbi_set_flip_vertically_on_load(1);
    m_localBuffer = stbi_load(path.c_str(), &m_width, &m_height, &m_channels, 0);

    GLenum format;
    if (m_channels == 1) {
        format = GL_RED;
    } else if (m_channels == 3) {
        format = GL_RGB;
    } else if (m_channels == 4) {
        format = GL_RGBA;
    }

    glGenTextures(1, &m_rendererId);
    glBindTexture(GL_TEXTURE_2D, m_rendererId);

    // 设置纹理环绕方式
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    // 纹理被缩小时使用临近过滤
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    // 纹理被放大时使用线性过滤
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    // 生成纹理
    glTexImage2D(GL_TEXTURE_2D, 0, format, m_width, m_height, 0, format, GL_UNSIGNED_BYTE, m_localBuffer);
    glGenerateMipmap(GL_TEXTURE_2D);

    if (m_localBuffer)
        stbi_image_free(m_localBuffer);
}

Texture2D::~Texture2D()
{
    glDeleteTextures(1, &m_rendererId);
}

void Texture2D::bind(unsigned int slot) const
{
    // 在绑定纹理之前先激活纹理单元
    glActiveTexture(GL_TEXTURE0 + slot);
    glBindTexture(GL_TEXTURE_2D, m_rendererId);
}

void Texture2D::unbind() const
{
    glBindTexture(GL_TEXTURE_2D, 0);
}
